﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using InstrumentationLibrary;
using InstrumentationLibrary.Implementation.Config;
using InstrumentationLibrary.Implementation.Interfaces;
using Mono.Cecil;

namespace InstrumentationLibrary.Implementation
{
    public class InstrumentationLibrary : IInstrumentationLibrary
    {
        private readonly string _assemblyPath;
        private readonly AssemblyDefinition _assemblyDefinition;
        private readonly InstrumentationConfig _instrumentationConfig;

        private IList<MethodDefinition> _methodsToRW;
        private IInstrumentationAspect _instrumentationAspect;

        public InstrumentationLibrary(InstrumentationConfig instrumentationConfig)
        {
            _assemblyPath = instrumentationConfig.AssemblyPath;
            _assemblyDefinition = AssemblyDefinition.ReadAssembly(_assemblyPath);
            _instrumentationConfig = instrumentationConfig;
            IList<MethodDefinition> methodsToRW = new List<MethodDefinition>();
            LocateAllMethods();
        }

        public void LocateAllMethods()
        {
            foreach (ConfigMethod method in _instrumentationConfig.Methods)
            {
                var fullTypeList = _assemblyDefinition.MainModule.Types;
                var specificType = fullTypeList.First(x => x.Name.Equals(method.Type));

                foreach (MethodDefinition methodDefinition in specificType.Methods)
                {
                    if (methodDefinition.Name == method.Name)
                    {
                        _methodsToRW.Add(methodDefinition);
                    }
                }
            }

            if (_methodsToRW.Count == 0)
                Console.WriteLine("No methods found matching your configuration");
            else
                Console.WriteLine("{0} methods found matching your configuration", _methodsToRW.Count);
        }

        public void Instrument()
        {
            if (_methodsToRW.Count != 0)
            {
                _instrumentationAspect.Instrument(_methodsToRW);
            }
        }
    }
}
